package com.love.cloud.common.zzd.api;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.alibaba.xxpt.gateway.shared.api.request.*;
import com.alibaba.xxpt.gateway.shared.api.response.*;
import com.alibaba.xxpt.gateway.shared.client.http.ExecutableClient;
import com.alibaba.xxpt.gateway.shared.client.http.IntelligentGetClient;
import com.alibaba.xxpt.gateway.shared.client.http.IntelligentPostClient;
import com.alibaba.xxpt.gateway.shared.client.http.PostClient;
import com.love.cloud.common.core.exception.BusinessException;
import com.love.cloud.common.core.util.RedisUtils;
import com.love.cloud.common.zzd.dto.*;
import com.love.cloud.common.zzd.enums.SendDingV2Enum;
import com.love.cloud.common.zzd.properties.DingTalkProperties;
import com.love.cloud.common.zzd.utils.ExpiryMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Description: 浙江政务钉钉接口请求类
 * @author pryoyi@gmail.com
 * @date 2020/6/16 14:59
 */
@Service
@Slf4j
public class GovDingAPICaller {

    @Resource
    private DingTalkProperties dingTalkProperties;
    @Resource
    private RedisUtils redisUtils;
    /**
     * redis 存储的钉AccessToken的key
     */
    private static final String dingAccessTokenKey="dingAccessToken";


    /**
     * 获取到钉钉客户端信息，并且初始化客户端
     * @return
     */
    private synchronized ExecutableClient getExecutableClientInstance() {
        ExecutableClient executableClient = null;
        if (StrUtil.isEmpty(dingTalkProperties.getAppKey())){ return new ExecutableClient(); }
        String key = dingTalkProperties.getAppCode() + "ExecutableClient";
        if (!ExpiryMap.getInstance().containsKey(SecureUtil.md5(key))){
            ExecutableClient temp = new ExecutableClient();
            temp.setAccessKey(dingTalkProperties.getAppKey());
            temp.setSecretKey(dingTalkProperties.getAppSecret());
            temp.setDomainName(dingTalkProperties.getBaseUrl());
            temp.setProtocal("https");
            temp.init();
            ExpiryMap.getInstance().put(SecureUtil.md5(key), temp);
        }
        executableClient = (ExecutableClient) ExpiryMap.getInstance().get(SecureUtil.md5(key));
        return executableClient;
    }

    /**
     * 获取到钉钉客户端信息，并且初始化客户端
     * @return
     */
    private synchronized ExecutableClient getExecutableAuthClientInstance() {
        ExecutableClient executableClient = null;
        if (StrUtil.isEmpty(dingTalkProperties.getAuthAppKey())){ return this.getExecutableClientInstance(); }
        String key = StringUtils.isNotEmpty(dingTalkProperties.getAuthAppCode())?dingTalkProperties.getAuthAppCode():dingTalkProperties.getAppCode() + "AuthExecutableClient";
        if (!ExpiryMap.getInstance().containsKey(SecureUtil.md5(key))){
            ExecutableClient temp = new ExecutableClient();
            temp.setAccessKey(dingTalkProperties.getAuthAppKey());
            temp.setSecretKey(dingTalkProperties.getAuthAppSecret());
            temp.setDomainName(dingTalkProperties.getBaseUrl());
            temp.setProtocal("https");
            temp.init();
            ExpiryMap.getInstance().put(SecureUtil.md5(key), temp);
        }
        executableClient = (ExecutableClient) ExpiryMap.getInstance().get(SecureUtil.md5(key));
        return executableClient;
    }


    /**
     * 获取到钉钉的accessToken
     * @return
     */
    public String getToken(String code){
        //先从redis中获取到有效时间内的token
        Object o = redisUtils.get(dingAccessTokenKey+"::"+code);
        if(o!=null){
            return (String)o;
        }else{
            return this.handleGetToken(code);
        }
    }
    /**
     * 执行获取去到token
     * @param code
     * @return
     */
    private synchronized String handleGetToken(String code){
        //双检索
        Object o = redisUtils.get(dingAccessTokenKey+"::"+code);
        if(o!=null){
            return (String)o;
        }else {
            //从钉钉中获取到最新accessToken
            boolean isAuth = "auth".equals(code);
            //executableClient保证单例
            IntelligentGetClient intelligentGetClient = (isAuth?getExecutableAuthClientInstance():getExecutableClientInstance()).newIntelligentGetClient("/gettoken.json");
            OapiGettokenJsonRequest oapiGettokenJsonRequest = new OapiGettokenJsonRequest();
            //应用的唯一标识key
            oapiGettokenJsonRequest.setAppkey((isAuth&&StringUtils.isNotEmpty(dingTalkProperties.getAuthAppKey()))?dingTalkProperties.getAuthAppKey():dingTalkProperties.getAppKey());
            //应用的密钥
            oapiGettokenJsonRequest.setAppsecret((isAuth&&StringUtils.isNotEmpty(dingTalkProperties.getAuthAppKey()))?dingTalkProperties.getAuthAppSecret():dingTalkProperties.getAppSecret());
            //获取结果
            OapiGettokenJsonResponse apiResult = intelligentGetClient.get(oapiGettokenJsonRequest);
            if(apiResult.getSuccess()&&apiResult.getContent().getSuccess()){
                String data = apiResult.getContent().getData();
                JSONObject jsonObject = JSON.parseObject(data);
                String accessToken = jsonObject.getString("accessToken");
                String expiresIn = jsonObject.getString("expiresIn");
                //防止接口延迟有误差所以redis剩余有效时间和钉钉返回的时间少20秒
                redisUtils.set(dingAccessTokenKey,accessToken, Integer.valueOf(expiresIn)-20, TimeUnit.SECONDS);
                return accessToken;
            }else{
                log.error("获取到浙政钉access_token异常信息：："+apiResult.getMessage());
            }
            return "";
        }

    }

    /**
     * JSAPI鉴权-获取jsapi_token，
     */
    public String getJsApiToken(){
        String data="";
        IntelligentGetClient intelligentGetClient =  getExecutableClientInstance().newIntelligentGetClient("/get_jsapi_token.json");
        OapiGetJsapiTokenJsonRequest oapiGetJsapiTokenJsonRequest = new OapiGetJsapiTokenJsonRequest();
        //null
        oapiGetJsapiTokenJsonRequest.setAccessToken(this.getToken("sync"));
        //获取结果
        OapiGetJsapiTokenJsonResponse apiResult = intelligentGetClient.get(oapiGetJsapiTokenJsonRequest);
        if(apiResult.getSuccess()&&apiResult.getContent().getSuccess()){
            data=apiResult.getContent().getData();
        }
        return data;
    }

    /**
     * 通过id来获取employeeCode
     * 案例参考地址：https://openplatform-portal.dg-work.cn/backendManage/#/docs?apiType=serverapi&docKey=2674900
     * @param accountId
     * @return
     */
    public String getEmployeeCodeByAccountId(String accountId) {
        String employeeCode="";
        PostClient postClient = getExecutableClientInstance().newPostClient("/mozi/employee/listGovEmployeeCodesByAccountIds");
        postClient.addParameter("accountIds", accountId);
        postClient.addParameter("tenantId", String.valueOf(dingTalkProperties.getTenantId()));
        String post = postClient.post();
        if(StringUtils.isNotEmpty(post)){
            JSONObject jsonObject = JSON.parseObject(post);
            //判断网关返回是否成功
            if(jsonObject.getBoolean("success")){
                JSONObject content = jsonObject.getJSONObject("content");
                //判断业务是否返回成功
                if(content.getBoolean("success")){
                    //获取到其中的员工信息
                    JSONArray data = content.getJSONArray("data");
                    for (Object info:data) {
                        JSONObject employeeCodeInfo=(JSONObject) info;
                        employeeCode= employeeCodeInfo.getString("employeeCode");
                        break;
                    }
                }
            }
        }
        return employeeCode;
    }


    /**
     * 获取到用户信息通过手机号（批量）手机号用逗号隔开
     * @param mobiles
     */
    public String getUserInfoByMobiles(String mobiles){
        return loadUserInfoByMobile(mobiles,"/mozi/employee/get_by_mobiles");
    }

    /**
     * 获取到用户信息通过手机号单个
     * @param mobile
     */
    public String getUserInfoByMobile(String mobile){
        String data="";
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/employee/get_by_mobile");
        OapiMoziEmployeeGetByMobileRequest oapiMoziEmployeeGetByMobileRequest = new OapiMoziEmployeeGetByMobileRequest();
        //手机区号
        oapiMoziEmployeeGetByMobileRequest.setAreaCode("86");
        //租户ID
        oapiMoziEmployeeGetByMobileRequest.setTenantId(dingTalkProperties.getTenantId());
        //账号类型
        oapiMoziEmployeeGetByMobileRequest.setNamespace("local");
        //手机号
        oapiMoziEmployeeGetByMobileRequest.setMobile(mobile);
        //获取结果
        OapiMoziEmployeeGetByMobileResponse apiResult = intelligentGetClient.get(oapiMoziEmployeeGetByMobileRequest);
        if(apiResult.getSuccess()&&apiResult.getContent().getSuccess()){
            data=apiResult.getContent().getData();
        }
        return data;
    }

    /**
     * 通过手机号获取浙政钉id
     * @param mobile
     */
    public String getDingAccountIdByMobile(String mobile){
        String data= this.getUserInfoByMobile(mobile);
        return getDingAccountIds(data, false);
    }

    /**
     * 通过手机号获取浙政钉id
     * @param mobileSet
     */
    public List<MobileAccountIdDto> getDingAccountIdsByMobileSet(Set<String> mobileSet){
        List<MobileAccountIdDto> list=new ArrayList<>();
        String mobileStr= String.join(",", mobileSet);
        String data= this.getUserInfoByMobile(mobileStr);
        if(StringUtils.isNotEmpty(data)) {
            list =JSON.parseObject(data,new TypeReference<ArrayList<MobileAccountIdDto>>(){});
        }
        return list;
    }


    /**
     * 通过手机号获取浙政钉id
     * @param mobile
     */
    public String getDingUserCodeByMobile(String mobile){
        String data= this.getUserInfoByMobile(mobile);
        return getUserParameter(data, false,"employeeCode");
    }

    /**
     * 加载用户信息通过手机号（批量手机号和单个手机号都是这个）
     * @param mobiles
     * @param api
     * @return
     */
    private String loadUserInfoByMobile(String mobiles, String api){
        String data="";
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient(api);
        OapiMoziEmployeeGetByMobilesRequest oapiMoziEmployeeGetByMobilesRequest = new OapiMoziEmployeeGetByMobilesRequest();
        //手机区号(没有特别说明，固定填写86)
        oapiMoziEmployeeGetByMobilesRequest.setAreaCode("86");
        //手机号码列表，逗号分隔，最多50个
        oapiMoziEmployeeGetByMobilesRequest.setMobiles(mobiles);
        //租户ID
        oapiMoziEmployeeGetByMobilesRequest.setTenantId(dingTalkProperties.getTenantId());
        //账号类型（没有特别说明,固定填写local）
        oapiMoziEmployeeGetByMobilesRequest.setNamespace("local");
        //获取结果
        OapiMoziEmployeeGetByMobilesResponse apiResult = intelligentGetClient.get(oapiMoziEmployeeGetByMobilesRequest);
        if(apiResult.getSuccess()&&apiResult.getContent().getSuccess()){
            data=apiResult.getContent().getData();
        }
        return data;
    }

    /**
     * 发送工作消息通过手机号
     * @param mobiles
     */
    public OapiMessageWorkNotificationResponse sendWorkMsgByMobiles(String[] mobiles, String message){
        String mobileStr= String.join(",", mobiles);
        String data= this.getUserInfoByMobiles(mobileStr);
        String dingAccountIds = getDingAccountIds(data, true);
        return this.handleMessage(message,dingAccountIds);
    }

    /**
     * 发送工作消息通过手机号
     * @param mobiles
     */
    public OapiMessageWorkNotificationResponse sendWorkMsgByMobiles(Set<String> mobiles, String message){
        String mobileStr= String.join(",", mobiles);
        String data= this.getUserInfoByMobiles(mobileStr);
        String dingAccountIds = getDingAccountIds(data, true);
        return this.handleMessage(message,dingAccountIds);
    }

    /**
     * 通过手机号获取到
     */

    /**
     * 发送工作消息通过手机号(单个手机号)
     * @param mobile
     */
    public OapiMessageWorkNotificationResponse sendWorkMsgByMobile(String mobile, String message){
        String data= this.getUserInfoByMobile(mobile);
        String dingAccountIds = getDingAccountIds(data, false);
        return this.handleMessage(message,dingAccountIds);
    }

    /**
     * 获取到浙政钉id
     * @param data
     * @return
     */
    public String getDingAccountIds(String data, boolean isArray){
        String dingAccountIds="";
        if(StringUtils.isNotEmpty(data)){
            if(isArray){
                JSONArray objects = JSON.parseArray(data);
                for (Object object:objects) {
                    if(StringUtils.isNotEmpty(dingAccountIds)){
                        dingAccountIds+=","+((JSONObject)object).getString("accountId");
                    }else{
                        dingAccountIds=((JSONObject)object).getString("accountId");
                    }
                }
            }else{
                JSONObject objects = JSON.parseObject(data);
                dingAccountIds= objects.getString("accountId");
            }
        }
        return dingAccountIds;
    }

    /**
     * 获取到获取到用户信息的属性
     * @param data
     * @return
     */
    public String getUserParameter(String data, boolean isArray,String parameterName){
        String param="";
        if(StringUtils.isNotEmpty(data)){
            if(isArray){
                JSONArray objects = JSON.parseArray(data);
                for (Object object:objects) {
                    if(StringUtils.isNotEmpty(param)){
                        param+=","+((JSONObject)object).getString(parameterName);
                    }else{
                        param=((JSONObject)object).getString(parameterName);
                    }
                }
            }else{
                JSONObject objects = JSON.parseObject(data);
                param= objects.getString(parameterName);
            }
        }
        return param;
    }
    /**
     * 执行发送消息
     * @param message
     * @param dingAccountIds 浙政钉id 多个通过逗号隔开
     */
    public OapiMessageWorkNotificationResponse handleMessage(String message, String dingAccountIds){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/message/workNotification");
        OapiMessageWorkNotificationRequest oapiMessageWorkNotificationRequest = new OapiMessageWorkNotificationRequest();
        //接收人用户ID
        oapiMessageWorkNotificationRequest.setReceiverIds(dingAccountIds);
        //租户ID
        oapiMessageWorkNotificationRequest.setTenantId(String.valueOf(dingTalkProperties.getTenantId()));
        String messageData= "{\"msgtype\":\"text\",\"text\":{\"content\":\""+message+"\"}}";
        //消息对象
        oapiMessageWorkNotificationRequest.setMsg(messageData);
        //获取结果
        OapiMessageWorkNotificationResponse apiResult = intelligentGetClient.get(oapiMessageWorkNotificationRequest);
        return apiResult;
    }

    /**
     * 分页获取下一级行政区划列表
     * @param divisionCode
     * @param pageNo
     * @param pageSize
     * @return
     */
    public OapiMoziOrganizationPageSubGovDivisionsResponse getSubGovDivisions(String divisionCode, int pageNo, int pageSize){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/organization/pageSubGovDivisions");
        OapiMoziOrganizationPageSubGovDivisionsRequest oapiMoziOrganizationPageSubGovDivisionsRequest = new OapiMoziOrganizationPageSubGovDivisionsRequest();
        //是否返回查询结果总数  默认不需要
        oapiMoziOrganizationPageSubGovDivisionsRequest.setReturnTotalSize(true);
        //每页条数, 默认20, 最大只能100
        oapiMoziOrganizationPageSubGovDivisionsRequest.setPageSize(pageSize);
        //行政区划 Code* 如果不填，默认查询第一级行政区划
        oapiMoziOrganizationPageSubGovDivisionsRequest.setDivisionCode(divisionCode);
        //当前页码, 开始页码为1, 小于1认为为1
        oapiMoziOrganizationPageSubGovDivisionsRequest.setPageNo(pageNo);
        //租户Id
        oapiMoziOrganizationPageSubGovDivisionsRequest.setTenantId(dingTalkProperties.getTenantId());
        //获取结果
        OapiMoziOrganizationPageSubGovDivisionsResponse apiResult = intelligentGetClient.get(oapiMoziOrganizationPageSubGovDivisionsRequest);
        return apiResult;
    }

    /**
     * 获取都下一级的线级
     * @param divisionCode
     * @param pageNo
     * @param pageSize
     * @return
     */
    public OapiMoziOrganizationPageSubGovBusinessStripsResponse pageSubGovBusinessStrips(String divisionCode, int pageNo, int pageSize){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/organization/pageSubGovBusinessStrips");
        OapiMoziOrganizationPageSubGovBusinessStripsRequest oapiMoziOrganizationPageSubGovBusinessStripsRequest = new OapiMoziOrganizationPageSubGovBusinessStripsRequest();
        //是否返回查询结果总数  默认不需要
        oapiMoziOrganizationPageSubGovBusinessStripsRequest.setReturnTotalSize(true);
        //条线Code 如果不填，默认查询第一级条线
        oapiMoziOrganizationPageSubGovBusinessStripsRequest.setBusinessStripCode(divisionCode);
        //每页条数, 默认20, 最大只能100
        oapiMoziOrganizationPageSubGovBusinessStripsRequest.setPageSize(pageSize);
        //当前页码, 开始页码为1, 小于1认为为1
        oapiMoziOrganizationPageSubGovBusinessStripsRequest.setPageNo(pageNo);
        //租户Id
        oapiMoziOrganizationPageSubGovBusinessStripsRequest.setTenantId(dingTalkProperties.getTenantId());
        //获取结果
        OapiMoziOrganizationPageSubGovBusinessStripsResponse apiResult = intelligentGetClient.get(oapiMoziOrganizationPageSubGovBusinessStripsRequest);
        return apiResult;
    }

    /**
     * DING API开放接口V2版本。
     * @return
     */
    public OapiDingIsvSendJsonResponse sendDingV2(SendDingV2Enum sendDingV2Enum, String content, SendDingV2CreatorDto creatorDto, List<SendDingV2ReceiverDto> receiverDtoList, SendDingV2SourceDto sourceDto){
        IntelligentGetClient intelligentGetClient =  getExecutableClientInstance().newIntelligentGetClient("/ding/isv/send.json");
        OapiDingIsvSendJsonRequest oapiDingIsvSendJsonRequest = new OapiDingIsvSendJsonRequest();
        if(receiverDtoList==null||receiverDtoList.size()==0){
            throw new BusinessException("请传入接收人的信息");
        }
        List<String> receiverList=new ArrayList<>();
        receiverList.add(JSON.toJSONString(receiverDtoList));
        if(sourceDto!=null){
            //来源
            oapiDingIsvSendJsonRequest.setSource(JSON.toJSONString(sourceDto));
        }
        //创建者
        oapiDingIsvSendJsonRequest.setCreator(JSON.toJSONString(creatorDto));
        //接收者
        oapiDingIsvSendJsonRequest.setReceivers(receiverList);
        //消息体类型
        oapiDingIsvSendJsonRequest.setBodyType("text");
        //内容类型
        oapiDingIsvSendJsonRequest.setDingBodyContentType("text");
        //消息体文本类型
        oapiDingIsvSendJsonRequest.setDingBodyTextType("plaintext");
        //消息体
        oapiDingIsvSendJsonRequest.setDingBody("{\"text\":\""+content+"\"}");
        //文本类型
        oapiDingIsvSendJsonRequest.setTextType("plaintext");
        //消息体
        oapiDingIsvSendJsonRequest.setBody("{\"text\":\""+content+"\"}");
        //通知类型
        oapiDingIsvSendJsonRequest.setNotifyType(sendDingV2Enum.getType());
        //租户ID
        oapiDingIsvSendJsonRequest.setTenantId(String.valueOf(dingTalkProperties.getTenantId()));
        //是否发送到IM
        oapiDingIsvSendJsonRequest.setSendToIm(true);
        //账户ID
        oapiDingIsvSendJsonRequest.setAccountId(creatorDto.getAccountId());
        //账户名称
        oapiDingIsvSendJsonRequest.setAccountName(creatorDto.getAccountName());
        //账户组织名称
        oapiDingIsvSendJsonRequest.setAccountOrgName(creatorDto.getAccountOrgName());
        //账户组织ID
        oapiDingIsvSendJsonRequest.setAccountOrgId(creatorDto.getAccountOrgId());
        //获取结果
        OapiDingIsvSendJsonResponse apiResult = intelligentGetClient.get(oapiDingIsvSendJsonRequest);
        return apiResult;
    }

    /**
     * 根据行政区划Code查询行政区划线
     * @param divisionCode
     * @return
     */
    public OapiMoziOrganizationGetDivisionLineResponse getDivisionLine(String divisionCode){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/organization/getDivisionLine");
        OapiMoziOrganizationGetDivisionLineRequest oapiMoziOrganizationGetDivisionLineRequest = new OapiMoziOrganizationGetDivisionLineRequest();
        //行政区划 Code
        oapiMoziOrganizationGetDivisionLineRequest.setDivisionCode(divisionCode);
        //租户Id
        oapiMoziOrganizationGetDivisionLineRequest.setTenantId(dingTalkProperties.getTenantId());
        //获取结果
        OapiMoziOrganizationGetDivisionLineResponse apiResult = intelligentGetClient.get(oapiMoziOrganizationGetDivisionLineRequest);
        return apiResult;
    }

    /**
     * 批量根据行政区划Code查询行政区划线
     * @param divisionCodeList
     * @return
     */
    public OapiMoziOrganizationListDivisionsByCodesResponse listDivisionsByCodes(List<String> divisionCodeList){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/organization/listDivisionsByCodes");
        OapiMoziOrganizationListDivisionsByCodesRequest oapiMoziOrganizationListDivisionsByCodesRequest = new OapiMoziOrganizationListDivisionsByCodesRequest();
        //行政区划 Code 列表
        oapiMoziOrganizationListDivisionsByCodesRequest.setDivisionCodes(divisionCodeList);
        //租户Id
        oapiMoziOrganizationListDivisionsByCodesRequest.setTenantId(dingTalkProperties.getTenantId());
        //获取结果
        OapiMoziOrganizationListDivisionsByCodesResponse apiResult = intelligentGetClient.get(oapiMoziOrganizationListDivisionsByCodesRequest);
        return apiResult;
    }


    /**
     * 批量根据行政区划Code查询行政区划线
     * @param divisionCodeList
     * @return
     */
    public List<DivisionsInfoDto> getDivisionsInfoList(List<String> divisionCodeList){
        List<DivisionsInfoDto> divisionsInfoDtoList=new ArrayList<>();
        OapiMoziOrganizationListDivisionsByCodesResponse response = this.listDivisionsByCodes(divisionCodeList);
        if(response.getSuccess()&&response.getContent().getSuccess()){
            if(StringUtils.isNotEmpty(response.getContent().getData())){
                divisionsInfoDtoList=JSON.parseObject(response.getContent().getData(),new TypeReference<ArrayList<DivisionsInfoDto>>(){});
            }
        }
        return divisionsInfoDtoList;
    }


    /*********************************组织相关的start*****************************************/
    /**
     * 浙政钉原生api调用
     * 获取到下级组织的编码
     * @param orgCode
     * @param pageNo
     * @param pageSize
     * @return
     */
    public OapiMoziOrganizationPageSubOrganizationCodesResponse pageSubOrganizationCodes(String orgCode, int pageNo, int pageSize){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/organization/pageSubOrganizationCodes");
        OapiMoziOrganizationPageSubOrganizationCodesRequest oapiMoziOrganizationPageSubOrganizationCodesRequest = new OapiMoziOrganizationPageSubOrganizationCodesRequest();
        oapiMoziOrganizationPageSubOrganizationCodesRequest.setReturnTotalSize(true);
        oapiMoziOrganizationPageSubOrganizationCodesRequest.setPageSize(pageSize);
        oapiMoziOrganizationPageSubOrganizationCodesRequest.setOrganizationCode(orgCode);
        oapiMoziOrganizationPageSubOrganizationCodesRequest.setPageNo(pageNo);
        oapiMoziOrganizationPageSubOrganizationCodesRequest.setStatus("A");
        oapiMoziOrganizationPageSubOrganizationCodesRequest.setTenantId(dingTalkProperties.getTenantId());
        //获取结果
        OapiMoziOrganizationPageSubOrganizationCodesResponse apiResult = intelligentGetClient.get(oapiMoziOrganizationPageSubOrganizationCodesRequest);
        return apiResult;
    }

    /**
     * 浙政钉原生api调用
     * 批量获取到组织详情
     * @param orgCodeList
     * @return
     */
    public OapiMoziOrganizationListOrganizationsByCodesResponse listOrganizationsByCodes(List<String> orgCodeList){
        //executableClient保证单例
        IntelligentPostClient intelligentPostClient =  getExecutableClientInstance().newIntelligentPostClient("/mozi/organization/listOrganizationsByCodes");
        OapiMoziOrganizationListOrganizationsByCodesRequest oapiMoziOrganizationListOrganizationsByCodesRequest = new OapiMoziOrganizationListOrganizationsByCodesRequest();
        oapiMoziOrganizationListOrganizationsByCodesRequest.setOrganizationCodes(orgCodeList);
        oapiMoziOrganizationListOrganizationsByCodesRequest.setTenantId(dingTalkProperties.getTenantId());
        //获取结果
        OapiMoziOrganizationListOrganizationsByCodesResponse apiResult = intelligentPostClient.post(oapiMoziOrganizationListOrganizationsByCodesRequest);
        return apiResult;
    }

    /**
     * 浙政钉原生api调用
     * 根据组织名称关键词进行组织信息查询
     * @param nameKeywords
     * @param inOrganizationCode
     * @param cascadeOrganizationCode
     * @param pageNo
     * @param pageSize
     * @return
     */
    public OapiMoziFusionPageSearchOrganizationResponse pageSearchOrganization(String nameKeywords, String inOrganizationCode, String cascadeOrganizationCode, int pageNo, int pageSize){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/fusion/pageSearchOrganization");
        OapiMoziFusionPageSearchOrganizationRequest oapiMoziFusionPageSearchOrganizationRequest = new OapiMoziFusionPageSearchOrganizationRequest();
        //是否返回查询结果总数  默认不需要
        oapiMoziFusionPageSearchOrganizationRequest.setReturnTotalSize(true);
        //组织code,在当前组织下查询 优先级高于cascadeOrganizationCode 两个参数至少有一个
        oapiMoziFusionPageSearchOrganizationRequest.setInOrganizationCode(inOrganizationCode);
        //每页条数, 默认20, 最大只能100
        oapiMoziFusionPageSearchOrganizationRequest.setPageSize(pageSize);
        //当前页码, 开始页码为1, 小于1认为为1
        oapiMoziFusionPageSearchOrganizationRequest.setPageNo(pageNo);
        //租户ID
        oapiMoziFusionPageSearchOrganizationRequest.setTenantId(dingTalkProperties.getTenantId());
        //组织code,在组织级联下级中查询
        oapiMoziFusionPageSearchOrganizationRequest.setCascadeOrganizationCode(cascadeOrganizationCode);
        //A/F（可用/冻结） 默认返回所有
        oapiMoziFusionPageSearchOrganizationRequest.setStatus("A");
        //组织姓名关键字
        oapiMoziFusionPageSearchOrganizationRequest.setNameKeywords(nameKeywords);
        //获取结果
        OapiMoziFusionPageSearchOrganizationResponse apiResult = intelligentGetClient.get(oapiMoziFusionPageSearchOrganizationRequest);
        return apiResult;
    }


    /**
     * 浙政钉原生api调用
     * 根据组织Code查询组织汇报线
     * @param organizationCode
     * @return
     */
    public OapiMoziOrganizationGetOrganizationLineResponse getOrganizationLine(String organizationCode){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/organization/getOrganizationLine");
        OapiMoziOrganizationGetOrganizationLineRequest oapiMoziOrganizationGetOrganizationLineRequest = new OapiMoziOrganizationGetOrganizationLineRequest();
        oapiMoziOrganizationGetOrganizationLineRequest.setOrganizationCode(organizationCode);
        oapiMoziOrganizationGetOrganizationLineRequest.setTenantId(dingTalkProperties.getTenantId());
        //获取结果
        OapiMoziOrganizationGetOrganizationLineResponse apiResult = intelligentGetClient.get(oapiMoziOrganizationGetOrganizationLineRequest);
        return apiResult;
    }


    /**
     * 浙政钉原生api调用
     * 根据组织Code获取组织汇报线(包含名称)
     * @param organizationCode
     * @return
     */
    public OapiMoziOrganizationGetOrganizationPathResponse getOrganizationPath(String organizationCode){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/organization/getOrganizationPath");
        OapiMoziOrganizationGetOrganizationPathRequest oapiMoziOrganizationGetOrganizationPathRequest = new OapiMoziOrganizationGetOrganizationPathRequest();
        //组织code
        oapiMoziOrganizationGetOrganizationPathRequest.setOrganizationCode(organizationCode);
        //租户ID
        oapiMoziOrganizationGetOrganizationPathRequest.setTenantId(dingTalkProperties.getTenantId());
        //获取结果
        OapiMoziOrganizationGetOrganizationPathResponse apiResult = intelligentGetClient.get(oapiMoziOrganizationGetOrganizationPathRequest);
        return apiResult;
    }

    /**
     * 浙政钉原生api调用
     * 根据组织 Code 查询详情
     * @param organizationCode
     * @return
     */
    public OapiMoziOrganizationGetOrganizationByCodeResponse getOrganizationByCode(String organizationCode){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/organization/getOrganizationByCode");
        OapiMoziOrganizationGetOrganizationByCodeRequest oapiMoziOrganizationGetOrganizationByCodeRequest = new OapiMoziOrganizationGetOrganizationByCodeRequest();
        oapiMoziOrganizationGetOrganizationByCodeRequest.setOrganizationCode(organizationCode);
        oapiMoziOrganizationGetOrganizationByCodeRequest.setTenantId(dingTalkProperties.getTenantId());
        //获取结果
        OapiMoziOrganizationGetOrganizationByCodeResponse apiResult = intelligentGetClient.get(oapiMoziOrganizationGetOrganizationByCodeRequest);
        return apiResult;
    }

    /**
     * 拓展接口
     * 根据组织Code获取组织汇报线(包含名称)
     * @param organizationCode
     * @return
     */
    public List<DingOrgPathDto> getOrgPathByCode(String organizationCode){
        List<DingOrgPathDto> dingOrgPathDtoList=null;
        OapiMoziOrganizationGetOrganizationPathResponse response = this.getOrganizationPath(organizationCode);
        if(response.getSuccess()&&response.getContent().getSuccess()){
            dingOrgPathDtoList=JSON.parseObject(response.getContent().getData(),new TypeReference<ArrayList<DingOrgPathDto>>(){});
        }
        return dingOrgPathDtoList;
    }

    /**
     * 拓展接口
     * 根据组织 Code 查询详情
     * @param orgCode
     * @return
     */
    public DingTalkOrgDto getOrgInfoByCode(String orgCode){
        DingTalkOrgDto dingTalkOrgDto=null;
        OapiMoziOrganizationGetOrganizationByCodeResponse response = getOrganizationByCode(orgCode);
        if(response.getSuccess()&&response.getContent().getSuccess()){
            dingTalkOrgDto=JSON.parseObject(response.getContent().getData(), DingTalkOrgDto.class);
        }
        return dingTalkOrgDto;
    }




    /**
     * 拓展接口
     * 获取到组织列表通过组织编号集合
     * @param orgCodeList
     * @return
     */
    public List<DingTalkOrgDto> getOrgListByCodes(List<String> orgCodeList){
        List<DingTalkOrgDto> orgList=new ArrayList();
        return this.getOrgListByCodes(orgCodeList,orgList);
    }

    /**
     * 拓展接口
     * 获取到组织列表通过组织编号集合
     * @param orgCodeList
     * @return
     */
    public List<DingTalkOrgDto> getOrgListByCodes(List<String> orgCodeList, List<DingTalkOrgDto> orgList){
        OapiMoziOrganizationListOrganizationsByCodesResponse response = this.listOrganizationsByCodes(orgCodeList);
        if(response.getSuccess()&&response.getContent().getSuccess()){
            String data = response.getContent().getData();
            orgList=JSON.parseObject(data,new TypeReference<ArrayList<DingTalkOrgDto>>(){});
        }
        return orgList;
    }

    /**
     * 拓展接口
     * 获取到下级组织的列表
     * @param orgCode
     * @return
     */
    public List<DingTalkOrgDto> subOrganizationList(String orgCode){
        List<DingTalkOrgDto> orgList=new ArrayList();
        int page=0;
        int pageSize=100;
        Long totalSize=-1L;
        List<String> orgCodeList=new ArrayList<>();
        do{
            page++;
            //先获取到组织编号列表
            OapiMoziOrganizationPageSubOrganizationCodesResponse response = this.pageSubOrganizationCodes(orgCode, page, pageSize);
            if(!response.getSuccess()||!response.getContent().getSuccess()){
                return orgList;
            }
            //设置最大数量
            if(totalSize==-1){
                totalSize=response.getContent().getTotalSize();
            }
            List list = JSON.parseObject(response.getContent().getData(), List.class);
            if(list!=null){
                //获取到其中的数据
                orgCodeList.addAll(list);
            }
        }while (totalSize>page*pageSize);
        //获取到组织信息
        if(orgCodeList!=null&&orgCodeList.size()>0){
            orgList=this.getOrgListByCodes(orgCodeList,orgList);
        }
        return orgList;
    }


    /**
     * 拓展接口
     * 获取到检索的组织信息
     * @param nameKeywords
     * @param inOrganizationCode
     * @param cascadeOrganizationCode
     * @return
     */
    public List<OrganizationSearchDto> searchOrgList(String nameKeywords, String inOrganizationCode, String cascadeOrganizationCode){
        List<OrganizationSearchDto> orgList=new ArrayList();
        int page=1;
        int pageSize=30;
        OapiMoziFusionPageSearchOrganizationResponse response = this.pageSearchOrganization(nameKeywords, inOrganizationCode, cascadeOrganizationCode,page,pageSize);
        List<OrganizationSearchDto> list = JSON.parseObject(response.getContent().getData(), new TypeReference<ArrayList<OrganizationSearchDto>>(){});
        if(list!=null){
            //获取到其中的数据
            orgList.addAll(list);
        }
        return orgList;
    }

    /**
     * 拓展接口
     * 获取到上级组织的线
     * @param organizationCode
     * @return
     */
    public String[] getSuperiorLine(String organizationCode){
        String[] list={};
        OapiMoziOrganizationGetOrganizationLineResponse response = this.getOrganizationLine(organizationCode);
        if(response.getSuccess()&&response.getContent().getSuccess()){
            String[] orgList = JSON.parseObject(response.getContent().getData(), String[].class);
            int rootIndex=0;
            //截取到对应姐,正序,跳过当前组织
            for (int i = 1; i < orgList.length; i++) {
                if(orgList[i].equals(dingTalkProperties.getRootOrgCode())){
                    rootIndex=i;
                    break;
                }
            }
            list=new String[rootIndex];
            //把结果倒叙塞到新的数组中
            for (int i = rootIndex; i >0; i--) {
                list[rootIndex-i]=orgList[i];
            }
        }
        return list;
    }


    /*********************************组织相关的end*****************************************/



    /*********************************用户相关的start*****************************************/


    /**
     * 根据员工Code查询详情
     * @param employeeCode
     * @return
     */
    public OapiMoziEmployeeGetEmployeeByCodeResponse getEmployeeByCode(String employeeCode){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/employee/getEmployeeByCode");
        OapiMoziEmployeeGetEmployeeByCodeRequest oapiMoziEmployeeGetEmployeeByCodeRequest = new OapiMoziEmployeeGetEmployeeByCodeRequest();
        oapiMoziEmployeeGetEmployeeByCodeRequest.setEmployeeCode(employeeCode);
        oapiMoziEmployeeGetEmployeeByCodeRequest.setTenantId(dingTalkProperties.getTenantId());
        //获取结果
        OapiMoziEmployeeGetEmployeeByCodeResponse apiResult = intelligentGetClient.get(oapiMoziEmployeeGetEmployeeByCodeRequest);
        return apiResult;
    }

    /**
     * 获取到用户信息通过员工编号
     * @param employeeCode
     * @return
     */
    public DingTalkUserDto getDingTalkUserDtoByCode(String employeeCode){
        DingTalkUserDto dingTalkUserDto=null;
        if(StringUtils.isNotEmpty(employeeCode)){
            OapiMoziEmployeeGetEmployeeByCodeResponse response = this.getEmployeeByCode(employeeCode);
            if(response.getSuccess()&&response.getContent().getSuccess()){
                dingTalkUserDto = JSON.parseObject(response.getContent().getData(), DingTalkUserDto.class);
            }
        }
        return dingTalkUserDto;
    }


    /**
     * 浙政钉原生api调用
     * 分页查询组织下的员⼯ Code
     * @return
     */
    public OapiMoziOrganizationPageOrganizationEmployeeCodesResponse pageOrganizationEmployeeCodes(String orgCode, int pageNo, int pageSize){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/organization/pageOrganizationEmployeeCodes");
        OapiMoziOrganizationPageOrganizationEmployeeCodesRequest oapiMoziOrganizationPageOrganizationEmployeeCodesRequest = new OapiMoziOrganizationPageOrganizationEmployeeCodesRequest();
        //null
        oapiMoziOrganizationPageOrganizationEmployeeCodesRequest.setReturnTotalSize(true);
        oapiMoziOrganizationPageOrganizationEmployeeCodesRequest.setEmployeePositionStatus("A");
        oapiMoziOrganizationPageOrganizationEmployeeCodesRequest.setPageSize(pageSize);
        oapiMoziOrganizationPageOrganizationEmployeeCodesRequest.setOrganizationCode(orgCode);
        oapiMoziOrganizationPageOrganizationEmployeeCodesRequest.setPageNo(pageNo);
        oapiMoziOrganizationPageOrganizationEmployeeCodesRequest.setTenantId(dingTalkProperties.getTenantId());
        //获取结果
        OapiMoziOrganizationPageOrganizationEmployeeCodesResponse apiResult = intelligentGetClient.get(oapiMoziOrganizationPageOrganizationEmployeeCodesRequest);
        return apiResult;
    }

    /**
     * 浙政钉原生api调用
     * 批量根据员⼯Code查询详情
     * @param codeList
     * @return
     */
    public OapiMoziEmployeeListEmployeesByCodesResponse listEmployeesByCodes(List<String> codeList){
        //executableClient保证单例
        IntelligentPostClient intelligentPostClient = getExecutableClientInstance().newIntelligentPostClient("/mozi/employee/listEmployeesByCodes");
        OapiMoziEmployeeListEmployeesByCodesRequest oapiMoziEmployeeListEmployeesByCodesRequest = new OapiMoziEmployeeListEmployeesByCodesRequest();
        //null
        oapiMoziEmployeeListEmployeesByCodesRequest.setEmployeeCodes(codeList);
        //null
        oapiMoziEmployeeListEmployeesByCodesRequest.setTenantId(dingTalkProperties.getTenantId());
        //获取结果
        OapiMoziEmployeeListEmployeesByCodesResponse apiResult = intelligentPostClient.post(oapiMoziEmployeeListEmployeesByCodesRequest);
        return apiResult;
    }


    /**
     * 浙政钉原生api调用
     * 批量根据员⼯Code查询详情
     * @param codeList
     * @return
     */
    public List<EmployeeAccountIdDto> listEmployeeAccountIds(List<String> codeList){
        List<EmployeeAccountIdDto> list=new ArrayList<>();
        ExecutableClient executableClient = getExecutableClientInstance();

        String api ="/mozi/employee/listEmployeeAccountIds";
        PostClient postClient = executableClient.newPostClient(api);
        //设置参数
        codeList.forEach(code -> postClient.addParameter("employeeCodes", code));
        postClient.addParameter("tenantId", dingTalkProperties.getTenantId().toString());
        //调用API
        String apiResult = postClient.post();
        JSONObject jsonObject = JSON.parseObject(apiResult);
        if(jsonObject.getBoolean("success")&&jsonObject.getJSONObject("content")!=null&&jsonObject.getJSONObject("content").getBoolean("success")){
            list=jsonObject.getJSONObject("content").getObject("data",new TypeReference<ArrayList<EmployeeAccountIdDto>>(){});
        }
        return list;
    }


    /**
     * 浙政钉原生api调用
     * 根据员工code获取员工的任职
     * @param employeeCode
     * @return
     */
    public OapiMoziEmployeeListEmployeePositionsByEmployeeCodeResponse listEmployeePositionsByEmployeeCode(String employeeCode){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/employee/listEmployeePositionsByEmployeeCode");
        OapiMoziEmployeeListEmployeePositionsByEmployeeCodeRequest oapiMoziEmployeeListEmployeePositionsByEmployeeCodeRequest = new OapiMoziEmployeeListEmployeePositionsByEmployeeCodeRequest();
        oapiMoziEmployeeListEmployeePositionsByEmployeeCodeRequest.setEmployeePositionStatus("A");
        oapiMoziEmployeeListEmployeePositionsByEmployeeCodeRequest.setEmployeePositionType("EMPLOYEE_POSITION_MAIN");
        oapiMoziEmployeeListEmployeePositionsByEmployeeCodeRequest.setEmployeeCode(employeeCode);
        oapiMoziEmployeeListEmployeePositionsByEmployeeCodeRequest.setTenantId(dingTalkProperties.getTenantId());
        //获取结果
        OapiMoziEmployeeListEmployeePositionsByEmployeeCodeResponse apiResult = intelligentGetClient.get(oapiMoziEmployeeListEmployeePositionsByEmployeeCodeRequest);
        return apiResult;
    }

    /**
     * 浙政钉原生api调用
     * 根据姓名关键词进行人员信息查询
     * @param nameKeywords
     * @param inOrganizationCode
     * @param cascadeOrganizationCode
     * @param pageNo
     * @param pageSize
     * @return
     */
    public OapiMoziFusionPageSearchEmployeeResponse pageSearchEmployee(String nameKeywords, String inOrganizationCode, String cascadeOrganizationCode, int pageNo, int pageSize){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableClientInstance().newIntelligentGetClient("/mozi/fusion/pageSearchEmployee");
        OapiMoziFusionPageSearchEmployeeRequest oapiMoziFusionPageSearchEmployeeRequest = new OapiMoziFusionPageSearchEmployeeRequest();
        //是否返回查询结果总数  默认不需要
        oapiMoziFusionPageSearchEmployeeRequest.setReturnTotalSize(false);
        //组织code,在当前组织下查询 优先级高于cascadeOrganizationCode 两个参数至少有一个
        oapiMoziFusionPageSearchEmployeeRequest.setInOrganizationCode(inOrganizationCode);
        //每页条数, 默认20, 最大只能100
        oapiMoziFusionPageSearchEmployeeRequest.setPageSize(pageSize);
        //当前页码, 开始页码为1, 小于1认为为1
        oapiMoziFusionPageSearchEmployeeRequest.setPageNo(pageNo);
        //租户id
        oapiMoziFusionPageSearchEmployeeRequest.setTenantId(dingTalkProperties.getTenantId());
        //组织code,在组织级联下级中查询
        oapiMoziFusionPageSearchEmployeeRequest.setCascadeOrganizationCode(cascadeOrganizationCode);
        //A/F （在职/离职）默认返回所有
        oapiMoziFusionPageSearchEmployeeRequest.setStatus("A");
        //人员姓名关键字
        oapiMoziFusionPageSearchEmployeeRequest.setNameKeywords(nameKeywords);
        //获取结果
        OapiMoziFusionPageSearchEmployeeResponse apiResult = intelligentGetClient.get(oapiMoziFusionPageSearchEmployeeRequest);
        return apiResult;
    }

    /**
     * 根据组织code和批量员工 Code 获取员工的邮箱信息
     * @param employeeCodes 员工编号,多个用逗号隔开
     * @param organizationCode 组织编号
     * @return
     */
    public List<OrgEmployeeEmailDto> listGovOrgEmployeeEmailByCodes(String employeeCodes, String organizationCode){
        List<OrgEmployeeEmailDto> list=new ArrayList<>();;
        String api ="/mozi/employee/listGovOrgEmployeeEmailByCodes";
        ExecutableClient executableClient = getExecutableClientInstance();
        PostClient postClient = executableClient.newPostClient(api);
        //设置参数
        postClient.addParameter("employeeCodes", employeeCodes);
        postClient.addParameter("organizationCode", organizationCode);
        postClient.addParameter("tenantId", String.valueOf(dingTalkProperties.getTenantId()));
        //调用API
        String apiResult = postClient.post();
        JSONObject jsonObject = JSON.parseObject(apiResult);
        if(jsonObject.getBoolean("success")){
            list=jsonObject.getObject("data",new TypeReference<ArrayList<OrgEmployeeEmailDto>>(){});
        }
        return list;
    }


    /**
     * 拓展接口
     * 获取到检索的用户信息
     * @param nameKeywords
     * @param inOrganizationCode
     * @param cascadeOrganizationCode
     * @return
     */
    public List<EmployeeSearchDto> searchEmployeeList(String nameKeywords, String inOrganizationCode, String cascadeOrganizationCode){
        List<EmployeeSearchDto> userList=new ArrayList();
        int page=1;
        int pageSize=10;
        OapiMoziFusionPageSearchEmployeeResponse response = this.pageSearchEmployee(nameKeywords, inOrganizationCode, cascadeOrganizationCode,page,pageSize);
        List<EmployeeSearchDto> list = JSON.parseObject(response.getContent().getData(), new TypeReference<ArrayList<EmployeeSearchDto>>(){});
        if(list!=null){
            //获取到其中的数据
            userList.addAll(list);
        }
        return userList;
    }

    /**
     * 拓展接口
     * 获取到职位列表信息
     * @param employeeCode
     * @return
     */
    public List<DingTalkEmployeePositionsDto> employeePositionsList(String employeeCode){
        List<DingTalkEmployeePositionsDto> list=new ArrayList<>();
        OapiMoziEmployeeListEmployeePositionsByEmployeeCodeResponse response = this.listEmployeePositionsByEmployeeCode(employeeCode);
        if(response.getSuccess()&&response.getContent().getSuccess()){
            list=JSON.parseObject(response.getContent().getData(),new TypeReference<ArrayList<DingTalkEmployeePositionsDto>>(){});
        }
        return list;
    }

    /**
     * 拓展接口
     * 获取到用户相关的部门信息
     * @param employeeCode
     * @return
     */
    public List<DingTalkOrgDto> getUserOrgList(String employeeCode){
        List<DingTalkOrgDto> orgList=new ArrayList<>();
        List<DingTalkEmployeePositionsDto> positionsList = this.employeePositionsList(employeeCode);
        List<String> codeList = positionsList.stream().map(DingTalkEmployeePositionsDto::getOrganizationCode).collect(Collectors.toList());
        return this.getOrgListByCodes(codeList,orgList);
    }

    /**
     * 拓展接口
     * 获取到当前组织的用户列表
     * @param orgCode
     * @return
     */
    public List<DingTalkUserDto> organizationEmployeeList(String orgCode){
        List<DingTalkUserDto> userList=new ArrayList();
        int page=0;
        int pageSize=100;
        Long totalSize=-1L;
        List<String> userCodeList=new ArrayList<>();
        do{
            page++;
            //先获取到组织下面的用户编号
            OapiMoziOrganizationPageOrganizationEmployeeCodesResponse response = this.pageOrganizationEmployeeCodes(orgCode, page, pageSize);
            if(!response.getSuccess()||!response.getContent().getSuccess()){
                return userList;
            }
            //设置最大数量
            if(totalSize==-1){
                totalSize=response.getContent().getTotalSize();
            }
            List list = JSON.parseObject(response.getContent().getData(), List.class);
            if(list!=null){
                //获取到其中的数据
                userCodeList.addAll(list);
            }
        }while (totalSize>page*pageSize);
        //获取到用户信息
        if(userCodeList!=null&&userCodeList.size()>0){
            OapiMoziEmployeeListEmployeesByCodesResponse response = this.listEmployeesByCodes(userCodeList);
            if(response.getSuccess()&&response.getContent().getSuccess()){
                String data = response.getContent().getData();
                userList=JSON.parseObject(data,new TypeReference<ArrayList<DingTalkUserDto>>(){});
            }
            //获取到账号id的信息
            List<EmployeeAccountIdDto> accountIdList = this.listEmployeeAccountIds(userCodeList);
            if(accountIdList!=null&&accountIdList.size()>0){
                Map<String, List<EmployeeAccountIdDto>> userGroup = accountIdList.stream().collect(Collectors.groupingBy(EmployeeAccountIdDto::getEmployeeCode));
                for (DingTalkUserDto dingTalkUserDto:userList) {
                    List<EmployeeAccountIdDto> list = userGroup.get(dingTalkUserDto.getEmployeeCode());
                    if(list!=null&&list.size()>0){
                        dingTalkUserDto.setAccountId(list.get(0).getAccountId());
                        dingTalkUserDto.setAccountCode(list.get(0).getAccountCode());
                        dingTalkUserDto.setAccountNamespace(list.get(0).getAccountNamespace());
                    }
                }
            }
        }
        return userList;
    }

    /*********************************用户相关的end*****************************************/

    /**
     * 通过code来获取到用户信息(浙政钉内部临时码免登)
     */
    public OapiRpcOauth2DingtalkAppUserJsonResponse dingTalkAppUser(String code){
        //executableClient保证单例
        IntelligentPostClient intelligentPostClient = getExecutableAuthClientInstance().newIntelligentPostClient("/rpc/oauth2/dingtalk_app_user.json");
        OapiRpcOauth2DingtalkAppUserJsonRequest oapiRpcOauth2DingtalkAppUserJsonRequest = new OapiRpcOauth2DingtalkAppUserJsonRequest();
        //登录access_token
        oapiRpcOauth2DingtalkAppUserJsonRequest.setAccess_token(this.getToken("auth"));
        //临时授权码
        oapiRpcOauth2DingtalkAppUserJsonRequest.setAuth_code(code);
        //获取结果
        OapiRpcOauth2DingtalkAppUserJsonResponse apiResult = intelligentPostClient.post(oapiRpcOauth2DingtalkAppUserJsonRequest);
        return apiResult;
    }

    /**
     * 浙政钉应用内部
     * @param code
     * @return
     */
    public UserInfoByCodeDto getDingTalkAppUserDto(String code){
        OapiRpcOauth2DingtalkAppUserJsonResponse response = this.dingTalkAppUser(code);
        UserInfoByCodeDto userInfoByCodeDto=null;
        if(response.getSuccess()){
            userInfoByCodeDto=this.setUserInfoData(response.getContent());
        }
        return userInfoByCodeDto;
    }

    /**
     * 服务端通过临时授权码获取授权用户的个人信息（qrcode可以使用）
     * @param code
     * @return
     */
    public OapiRpcOauth2GetuserinfoBycodeJsonResponse getUserInfoByCode(String code){
        //executableClient保证单例
        IntelligentGetClient intelligentGetClient = getExecutableAuthClientInstance().newIntelligentGetClient("/rpc/oauth2/getuserinfo_bycode.json");
        OapiRpcOauth2GetuserinfoBycodeJsonRequest oapiRpcOauth2GetuserinfoBycodeJsonRequest = new OapiRpcOauth2GetuserinfoBycodeJsonRequest();
        //用户授权的临时授权码code，只能使用一次；在前面步骤中跳转到redirect_uri时会追加code参数
        oapiRpcOauth2GetuserinfoBycodeJsonRequest.setCode(code);
        //调用接口凭证，应用access_token
        oapiRpcOauth2GetuserinfoBycodeJsonRequest.setAccess_token(this.getToken("auth"));
        //获取结果
        OapiRpcOauth2GetuserinfoBycodeJsonResponse apiResult = intelligentGetClient.get(oapiRpcOauth2GetuserinfoBycodeJsonRequest);
        return apiResult;
    }

    /**
     * 获取到用户信息的dto
     * @param code
     * @return
     */
    public UserInfoByCodeDto getUserInfoDtoByCode(String code){
        UserInfoByCodeDto userInfoByCodeDto=null;
        OapiRpcOauth2GetuserinfoBycodeJsonResponse response = this.getUserInfoByCode(code);
        if(response.getSuccess()){
            userInfoByCodeDto=this.setUserInfoData(response.getContent());
        }
        return userInfoByCodeDto;
    }

    /**
     * 设置用户信息
     * @param contentStr
     */
    private UserInfoByCodeDto setUserInfoData(String contentStr){
        try{
            JSONObject jsonObject = JSON.parseObject(contentStr);
            if(jsonObject.getBoolean("success")){
                JSONObject content =jsonObject.getJSONObject("content");
                 return content.getObject("data", UserInfoByCodeDto.class);
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
        return null;
    }

}
